/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author antonio
 */
import java.util.Random;

public class Layer {
	public int n_nodes;
	public int order;
	public Node nodes[];
	CharSequence flow;
	int layer;
	int len;
	int portion;
	int rec[];
	
	public Layer(int n_nodes, int order)
	{
		this.n_nodes = n_nodes;
		this.order = order;
		this.nodes = new Node[this.n_nodes];
		this.portion = -Integer.MIN_VALUE;
		this.rec = new int[this.n_nodes];
				
		for(int i=0; i < this.n_nodes; i++)
		{
			nodes[i] = new Node(order,i);
		}
	}
	
	public void setInputStream(CharSequence in)
	{
		this.flow = in;
	}
	
	public void setLayer(int l)
	{
		this.layer = l;
		for(int i=0; i < this.n_nodes; i++)
		{
			nodes[i].setId(i, this.layer);
		}
	}
	
	public void assignInputToNode() throws Exception 
	{
		len = this.flow.length();
		portion = len/this.n_nodes;
		for(int i=0; i< this.n_nodes; i++)
		{
			CharSequence buffer = this.flow.subSequence(i*portion+1, (i+1)*portion);
			//System.out.println("Dim: " + portion + ", n_nodes: " + this.n_nodes + ", input_len: " + len);
			nodes[i].input(buffer);
		}
	}
	
	/* Randomly assigns input overlapped to node */
	public void assignInputToNodeFuzzy() throws Exception 
	{
		len = this.flow.length();
		//portion = len/this.n_nodes;
		Random rand = new Random();
		portion = 10 + rand.nextInt(len/this.n_nodes); 
		for(int i=0; i< this.n_nodes; i++)
		{
			int r;
			if(len>portion) 
				r = rand.nextInt(len-portion+1);
			else
				r = rand.nextInt(portion-len+1);
			CharSequence buffer = this.flow.subSequence(r, r + portion);
			//System.out.println("Dim: " + portion + ", n_nodes: " + this.n_nodes + ", input_len: " + len);
			nodes[i].input(buffer);
		}
	}
	
	public void assignInputToNodeFuzzyStable() throws Exception 
	{
		len = this.flow.length();
		//portion = len/this.n_nodes;
		if(this.portion == Integer.MIN_VALUE)
		{
			Random rand = new Random();
			//portion = 1 + rand.nextInt(len/this.n_nodes);
			if(len > 2)
				this.portion = 1 + rand.nextInt(len/2);
			else
				this.portion = 1 + rand.nextInt(len);
			for(int i=0; i< this.n_nodes; i++)
			{
				if(len>portion) 
					this.rec[i] = rand.nextInt(len-this.portion);
				else
					this.rec[i] = rand.nextInt(this.portion-len);
				CharSequence buffer = this.flow.subSequence(rec[i], rec[i] + this.portion);
				//System.out.println("Dim: " + portion + ", n_nodes: " + this.n_nodes + ", input_len: " + len);
				nodes[i].input(buffer);
			}
		}else
		{
			for(int i=0; i< this.n_nodes; i++)
			{
				CharSequence buffer = this.flow.subSequence(rec[i], rec[i] + this.portion);
				//System.out.println("Dim: " + portion + ", n_nodes: " + this.n_nodes + ", input_len: " + len);
				nodes[i].input(buffer);
			}
		}
	}
	
	
	public void assignInputToNodeSuperimposed() throws Exception 
	{
		len = this.flow.length();
		this.portion = (len/(this.n_nodes));
		for(int i=0; i< this.n_nodes; i++)
		{
			CharSequence buffer = this.flow.subSequence(i*portion+1, (i+1)*portion);
			/*String temp = (String) buffer; 
			temp += "";*/
			nodes[i].input(buffer);
		}
	}
	
	public void assignInputAsCompetition()
	{
		
	}
	
	public CharSequence outputStream() throws Exception
	{
		int count = 0;
		for(int i = 0; i < this.n_nodes; i++)
		{
			CharSequence bt = nodes[i].output();
			count += bt.length();
		}
		StringBuffer strb = new StringBuffer();
		strb.setLength(count+1);
		int kk = 0;
		for(int i = 0; i < this.n_nodes; i++)
		{
			CharSequence bt = nodes[i].output();
			for(int t = 0; t < bt.length(); t++)
			{
				//System.out.println("capacity:" + strb.capacity()+ ","+(kk+t));
				//strb.insert(kk+t, bt.charAt(t));
				strb.setCharAt(kk+t, bt.charAt(t));
			}
			kk += bt.length();
		}
		
		////////////////////////////////////////////////
		/*StringBuffer strb = new StringBuffer();
		CharSequence cs[] = new CharSequence[this.n_nodes]; 
		for(int i = 0; i < this.n_nodes; i++)
		{
			cs[i] = nodes[i].output();
		}
		for(int t = 0; t < cs[0].length(); t++)
		{
			for(int i = 0; i < this.n_nodes; i++)
			{
				strb.append(cs[i].charAt(t));
			}
		}*/
		return strb;
	}	
}